{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "870bc1d2",
   "metadata": {},
   "source": [
    "### 上周回顾  \n",
    "\n",
    "* 购物车程序项目：    \n",
    "  \n",
    "     1、运行程序后，让用户输入支付宝余额，然后打印我们的商品列表给用户。\n",
    "\n",
    "     2、让用户输入商品编号进行商品的购买。\n",
    "\n",
    "     3、用户选择商品后，检查用户的余额是否够，若够则直接扣款，不够则提醒用户。\n",
    "\n",
    "     4、用户可以随时退出购买，推出时打印用户已购买的商品和支付宝余额。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "018d08f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入您的余额：100\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：2.0\n",
      "请输入正确的【商品编号】！！ 或者按照提示进行输入\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：2\n",
      "【可乐】已经加入您的购物车，您的【余额】还有90元\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：3\n",
      "【炸鸡】已经加入您的购物车，您的【余额】还有60元\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：3\n",
      "【炸鸡】已经加入您的购物车，您的【余额】还有30元\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：2\n",
      "【可乐】已经加入您的购物车，您的【余额】还有20元\n",
      "---------- 商 品 清 单 ----------\n",
      "商品编号：0，商品名称:汉堡，商品价格：15元\n",
      "商品编号：1，商品名称:薯条，商品价格：18元\n",
      "商品编号：2，商品名称:可乐，商品价格：10元\n",
      "商品编号：3，商品名称:炸鸡，商品价格：30元\n",
      "商品编号：4，商品名称:鸡肉卷，商品价格：12元\n",
      "请输入正确的商品编号进行购买：q\n",
      "您的购物车： [['可乐', 10], ['炸鸡', 30], ['炸鸡', 30], ['可乐', 10]]\n",
      "您的账户余额：20元\n"
     ]
    }
   ],
   "source": [
    "# 1.让用户输入支付宝余额，然后打印我们的商品列表给用户\n",
    "goods_list = [\n",
    " #  [商品的名称 , 商品价格],\n",
    "    [\"汉堡\",15],\n",
    "    [\"薯条\",18],\n",
    "    [\"可乐\",10],\n",
    "    [\"炸鸡\",30],\n",
    "    [\"鸡肉卷\",12]\n",
    "]\n",
    "#写到某一步 发现前面需要内容，可以优化增加用append\n",
    "user_shopping_list = []     # 给用户一个购物车列表 初始是空的\n",
    "\n",
    "# 用户输入：input   \n",
    "Alipay = int(input(\"请输入您的余额：\"))  # 假设用户输入的是字符串数值 再用int将其转换为整数的数值    ---> 这里的数值默认用户输入的都为整数数字\n",
    "\n",
    "# 打印商品信息，打印商品的次数是由商品列表的长度决定的(len(goods_list))\n",
    "while True:  # 实现以下代码的循环\n",
    "    print(\"---------- 商 品 清 单 ----------\")\n",
    "    for i in range(len(goods_list)):\n",
    "        # 格式化的样式\n",
    "        # 样式：\"商品编号：xxx，商品名称：xxx，商品价格：xx\"\n",
    "        print(\"商品编号：%s，商品名称:%s，商品价格：%s元\" %(i,goods_list[i][0],goods_list[i][1]))\n",
    "\n",
    "    # 2.让用户输入商品编号进行商品的购买\n",
    "\n",
    "    # 用户输入商品编号\n",
    "    choice = input(\"请输入正确的商品编号进行购买：\")\n",
    "    if choice.isdigit():   # 用isdigit来判断字符串是否为数值 因为input输出的是字符串 （这个函数用于判断->）如果这个字符串是数字类型的（字符串的数值）\n",
    "        choice = int(choice)   # 如果字符串是数字类型的，就把把它强制转换为真正的 int（整数的数值）\n",
    "        \n",
    "        # 判断商品编号是否在 我们的范围内\n",
    "        # 3、用户选择商品后，检查用户的余额是否够，若够则直接扣款，不够则提醒用户。\n",
    "        if choice >= len(goods_list):\n",
    "            print(\"您输入的商品不存在，请检查再次输入\")\n",
    "        else:\n",
    "            # 对比商品编号，找到对应商品： 商品价格：goods_list[choice][1]\n",
    "            # 1.检查用户余额VS商品价格的关系\n",
    "            if Alipay > goods_list[choice][1]:\n",
    "                # 买得起 1.扣钱 2.把商品加到用户购物车中\n",
    "                Alipay = Alipay - goods_list[choice][1]\n",
    "                user_shopping_list.append(goods_list[choice])\n",
    "                print(\"【%s】已经加入您的购物车，您的【余额】还有%s元\"%(goods_list[choice][0],Alipay))\n",
    "            else:\n",
    "                print(\"您的余额不足以购买，请更换支付方式\")\n",
    "                \n",
    "    # 4、用户可以随时退出购买，推出时打印用户已购买的商品和支付宝余额\n",
    "    elif choice == \"q\":\n",
    "        # 如果用户输入q 则说明用户想退出程序了，打印用户的购物车列表 以及用户余额给用户\n",
    "        print(\"您的购物车：\",user_shopping_list)\n",
    "        print(\"您的账户余额：%s元\"%(Alipay))\n",
    "        break\n",
    "    else:\n",
    "        print(\"请输入正确的【商品编号】！！ 或者按照提示进行输入\")\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd6b21c0",
   "metadata": {},
   "source": [
    "# 本周学习\n",
    "## 元组 & 字典"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3f52b00",
   "metadata": {},
   "source": [
    "### 元组\n",
    "* [元组学习](https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences)  \n",
    "1. 它是和list几乎完全一样的序列数据\n",
    "2. 它与list不同的地方是**不可变** （因为不可变 目前只有两种方法count & index） 即输入的元组内对象的序列和输出的对象序列是一致的 \n",
    "3. 元组的形式：（1,2,36,25）    小括号包围对象 对象之间用,分隔\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "657b9753",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('100', '101', '103') <class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "stu_id = \"100\",\"101\",\"103\"\n",
    "print(stu_id,type(stu_id))   # type用来表示某个序列的类型（元组、集合、列表、字典）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8f9700d2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(250, 520, 360, '110')"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 元组的存储对象可以是数值、字符串\n",
    "t = 250,520,360,\"110\"\n",
    "t  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ae6408ca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'110'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 元组的取值方式类比列表\n",
    "t[1]   #  --> 520\n",
    "t[3]   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "33cee4ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((250, 520, 360, '110'), 120, '元组')\n"
     ]
    }
   ],
   "source": [
    "# 元组也可以嵌套   -->元组嵌套元组或元组嵌套其他对象\n",
    "a = t,120,\"元组\"\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "5965de78",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((250, 520, 360, '110'), ((250, 520, 360, '110'), 120, '元组'), ('a', 'b', 'c'))"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = t,a,(\"a\",\"b\",\"c\")\n",
    "b   # ---》 这也是一个元组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "69775b15",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([1, 2, 3], [3, 2, 1])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 元组可以嵌套有序的序列 如：列表\n",
    "c = ([1, 2, 3], [3, 2, 1])\n",
    "c   # 结果为元组   -----> 也就是说 元组可以嵌套多个列表 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "53662654",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(([1, 2, 3], [3, 2, 1]), ['a', 'v'], '5')"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = (c,['a','v'],\"5\")  # 一般来说存储在同一个容器中的对象类型最好要一致\n",
    "d    #  元组可以实现多级嵌套有序序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "949f645b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stu_id.count(\"101\")     # count 用来查询元组中某个对象的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "001de40e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stu_id.index(\"103\")     # index 用来查询元组中某个对象的索引值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "87d31f73",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=10, tm_mday=25, tm_hour=16, tm_min=23, tm_sec=25, tm_wday=0, tm_yday=298, tm_isdst=0)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import time\n",
    "time.localtime()    # 所打印出的9个时间格式 是用元组的方式呈现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9a961268",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "python <class 'str'>\n"
     ]
    }
   ],
   "source": [
    "# 特别注意！！！ 当元组序列中只有一个对象的时候 \n",
    "t1 = ('python')   # 这是一个只有一个对象的元组（其实不是）\n",
    "print(t1,type(t1))    # 结果是一个字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0231a61b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0,)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 正确的单个对象的元组写法： 一定要在对象的末尾处加上一个逗号 否则默认为字符串\n",
    "t2 = 0,\n",
    "type(t2)   #  ---> tuple\n",
    "len(t2)  # ---> 1     可以用len函数来检查这个元组的长度\n",
    "t2   # 结果为一个元组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ff232203",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'tuple'> 1\n"
     ]
    }
   ],
   "source": [
    "# 空元组     空括号是“no value”的非标准表示形式，添加尾随逗号将从“no value”生成元组。但它是一个具有“无值”项的元组，而不是空元组。\n",
    "t3 =(),    # 这是一个包含一个空元组的元组  相当于外面一个大元组包了一个小空元组\n",
    "print(type(t3),len(t3))   # 所以这个大元组其实是含有对象的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "1d156dbc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((),)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t3  # t3其实是一个嵌套型的元组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "d24235b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "empty = ()    \n",
    "len(empty)   #  --> 0\n",
    "empty\n",
    "type(empty)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8470ccf8",
   "metadata": {},
   "source": [
    "### 字典  \n",
    "* [字典学习](https://docs.python.org/3/tutorial/datastructures.html#dictionaries)  \n",
    "  1. 字典属于⼀种新的数据结构称为映射(mapping)\n",
    "  2. 字典我们也称之为键值对(key-value)结构\n",
    "  3. 字典一定要用{}包起来 ， 书写时最好把每组键值对换行写（如下1.）这样更易读\n",
    "  4. 在字典中每⼀个元素都有唯⼀的名字，通过这个唯⼀的名字可以找到指定的元素\n",
    "  5. 这个唯⼀的名字我们称之为key 通过key可以快速查询value 也可以称之为值\n",
    "  6. 字典的键是不能重复的，如果出现重复的后⾯的会替换前⾯的\n",
    "  7. 字典的值可以是任意对象 字典的键可以是任意的不可变对象(int str tuple…)\n",
    "---\n",
    "* 字典的特性：   \n",
    "\n",
    " 1. dict 是无序的\n",
    " 2. key 是唯一的\n",
    " 3. key 不可变性"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3314801d",
   "metadata": {},
   "source": [
    "#### 1.创建字典的三种常见方法\n",
    "* 1. 直接按照字典的格式创建：{key1:value1,key2:value2,...}\n",
    "* 2. dict()函数来创建字典：dict(key1=value1,key2=value2,...}\n",
    "* 3. 字典数据增加的方式 ：新建空字典 dict_name ={}，dict_name[key1]=value1 ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0d17cec2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'stud_01': 'a', 'stud_02': 'b', 'stud_03': 'c'}\n"
     ]
    }
   ],
   "source": [
    "# 1.{key1:value1,key2:value2,...}\n",
    "stud_info1 = {\n",
    "    \"stud_01\":\"a\",\n",
    "    \"stud_02\":\"b\",\n",
    "    \"stud_03\":\"c\"\n",
    "}\n",
    "print(stud_info1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "03be384e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'stud_01': 'a', 'stud_02': 'b', 'stud_03': 'c'}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 2.dict(key1=value1,key2=value2,...}\n",
    "stud_info2 = dict(\n",
    "    stud_01 = \"a\",\n",
    "    stud_02 = \"b\",\n",
    "    stud_03 = \"c\"\n",
    ")\n",
    "stud_info2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6bc1d15d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'stud_01': 'a', 'stud_02': 'b', 'stud_03': 'c'}\n"
     ]
    }
   ],
   "source": [
    "# 3.dict_name ={}，dict_name[key1]=value1 ...\n",
    "stud_info3 = {}\n",
    "stud_info3[\"stud_01\"] = \"a\"\n",
    "stud_info3[\"stud_02\"] = \"b\"\n",
    "stud_info3[\"stud_03\"] = \"c\"\n",
    "print(stud_info3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1485dff",
   "metadata": {},
   "source": [
    "#### 2. 字典的方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "c08f0d2d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李玟', 1005: '李显', 1006: '李群'}\n"
     ]
    }
   ],
   "source": [
    "# 创建一个字典\n",
    "stud = {\n",
    "    1001:\"李明\",\n",
    "    1002:\"李华\",\n",
    "    1003:\"李文\",\n",
    "    1004:\"李玟\",\n",
    "    1005:\"李显\",\n",
    "    1006:\"李群\"\n",
    "}\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "0ecfc020",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李玟', 1005: '李林', 1006: '李群', 1007: '李林'}\n"
     ]
    }
   ],
   "source": [
    "# 1.字典的增加        ---> 字典的增加方式： dict neme[key] = value   注意增加的键不能是已经存在的键名称  否则会覆盖原先字典那个键所对应的值\n",
    "stud[1007] = \"李林\"\n",
    "print(stud)      # 由于字典是无序的所以反馈的结果也是无序的 即字典的增加的对象的位置是随机的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "a27aceb7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1002: '李华', 1003: '李琳', 1004: '李玟', 1005: '李林', 1006: '李群', 1007: '李林'}\n"
     ]
    }
   ],
   "source": [
    "# 2.字典的修改      ---> 字典通过寻找键key来找对应的值value 所以可以通过键来修改其对应的值\n",
    "stud[1003] = \"李琳\"\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "7d0507ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1003: '李琳', 1004: '李玟', 1005: '李林', 1006: '李群', 1007: '李林'}\n"
     ]
    }
   ],
   "source": [
    "# 3.字典的删除  （3种方式）  \n",
    "# pop(key)  -->根据key删除对应的value   具有指向性\n",
    "stud.pop(1002)\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "d238828e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1003: '李琳', 1004: '李玟', 1005: '李林', 1006: '李群'}\n"
     ]
    }
   ],
   "source": [
    "# popitem()   --> 删除字典中随机一对key-value \n",
    "stud.popitem()\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "f32219d4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1003: '李琳', 1004: '李玟', 1006: '李群'}\n"
     ]
    }
   ],
   "source": [
    "# del dict name[key]    --> 根据键来删除一对键值对\n",
    "del stud[1005]\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "9aa83281",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "# 4.字典的查找\n",
    "stud = {\n",
    "    1001:\"李明\",\n",
    "    1002:\"李华\",\n",
    "    1003:\"李文\",\n",
    "    1004:\"李琳\",\n",
    "    1005:\"李玟\",\n",
    "    1006:\"李贺\"\n",
    "}\n",
    "# 使用in来检测字典中key是否存在\n",
    "print(1008 in stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "42cc0f12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "李文\n"
     ]
    }
   ],
   "source": [
    "# 通过键key来查找其对应的值value\n",
    "print(stud[1003])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "b89c6b49",
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "1009",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-38-324dc4fcd6fa>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# 如果所要查找的键不存在\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstud\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1009\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 1009"
     ]
    }
   ],
   "source": [
    "# 如果所要查找的键不存在就会报错\n",
    "print(stud[1009])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "f910247b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "李明\n"
     ]
    }
   ],
   "source": [
    "# get(key)  -->根据键来获取字典的值   使用get()方法的好处是当所要查找的值不存在时 它会返回一个 none  就不会报错\n",
    "print(stud.get(1001))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "e8ee792e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(stud.get(1010))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "e187c9c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "# 5. 字典的清除\n",
    "#  clear方法清除字典中所有的键值对   清空后会返回一个None\n",
    "print(stud.clear())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "a0c77f95",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n"
     ]
    }
   ],
   "source": [
    "stud = {\n",
    "    1001:\"李明\",\n",
    "    1002:\"李华\",\n",
    "    1003:\"李文\",\n",
    "    1004:\"李琳\",\n",
    "    1005:\"李玟\",\n",
    "    1006:\"李贺\"\n",
    "}\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "db0b6a29",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n"
     ]
    }
   ],
   "source": [
    "# 6.字典的复制\n",
    "# copy方法返回一个具有相同键值对的新字典   ---> 前提：这个字典中没有另外嵌套其他的序列\n",
    "stud1 = stud.copy()   # 先复制一个字典\n",
    "print(stud1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "7c1b8ad5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '小明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n",
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n"
     ]
    }
   ],
   "source": [
    "stud1[1001]=\"小明\"   # 对复印件字典进行修改替换值\n",
    "print(stud1)       \n",
    "print(stud)          # 原件字典没有改变"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "cdf07e26",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1001: '小明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺', 1010: '小林'}\n",
      "{1001: '李明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n"
     ]
    }
   ],
   "source": [
    "stud1[1010] = \"小林\"   # 对复印件字典增加对象\n",
    "print(stud1)\n",
    "print(stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "id": "871298bc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'username': 'xiao ho', 'have': ['cat', 'fish']}\n",
      "{'username': 'xiao ming', 'have': ['cat', 'fish']}\n"
     ]
    }
   ],
   "source": [
    "# 字典比较复杂时，其中嵌套了另外的字典或者列表时 用copy方法复制字典就是浅复制（父复制了，子还没有复制  即字典的父对象是独立的<修改新字典 原字典不变> 而子对象还是相同的<修改新字典，原字典也跟着被修改>）\n",
    "x={'username':'xiao ming','have':['cat','dog','fish']}\n",
    "y=x.copy()\n",
    "y['username']='xiao ho' # 修改字典的父对象即第一层级\n",
    "y['have'].remove('dog') # 修改字典的子对象即第二层级（字典中嵌套的其他序列）\n",
    "print(y)  # y的父对象变了，子对象（列表）变了\n",
    "print(x)  # x的父对象不变，子对象（列表）也变了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "id": "49995fae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'xiao ming', 'age': [25, 47]}\n",
      "{'name': 'xiao ming', 'age': [25, 47]}\n",
      "{'name': 'xiao ming', 'age': [25, 36, 47]}\n"
     ]
    }
   ],
   "source": [
    "# 避免上述问题，可以使用深复制 deepcopy函数\n",
    "from copy import deepcopy\n",
    "d = {'name':\"xiao ming\",\"age\":[25,36,47]}\n",
    "c = d.copy()  # c字典浅复制\n",
    "z = deepcopy(d)  # z字典深复制\n",
    "d['age'].remove(36)  # 删去原字典中的age对应值列表中的36\n",
    "print(d)\n",
    "print(c)\n",
    "print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "b60b1295",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这是原字典 {1001: '李明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '李玟', 1006: '李贺'}\n",
      "这是更新后的字典 {1001: '小明', 1002: '李华', 1003: '李文', 1004: '李琳', 1005: '小文', 1006: '李贺', 1010: '小兰'}\n"
     ]
    }
   ],
   "source": [
    "# 7.字典的更新\n",
    "# update方法可以利用一个字典更新另一个字典  如果键值存在则直接覆盖，如果不存在则会添加\n",
    "# 语法：dict.update(dict2)\n",
    "stud = {\n",
    "    1001:\"李明\",\n",
    "    1002:\"李华\",\n",
    "    1003:\"李文\",\n",
    "    1004:\"李琳\",\n",
    "    1005:\"李玟\",\n",
    "    1006:\"李贺\"\n",
    "}\n",
    "print(\"这是原字典\",stud)\n",
    "stud1 = {\n",
    "    1001:\"小明\",\n",
    "    1005:\"小文\",\n",
    "    1010:\"小兰\"\n",
    "}\n",
    "stud.update(stud1)    # 用stud1来更新stud字典\n",
    "print(\"这是更新后的字典\",stud)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "id": "2c01e647",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys([1001, 1002, 1003, 1004, 1005, 1006, 1010])\n",
      "dict_values(['小明', '李华', '李文', '李琳', '小文', '李贺', '小兰'])\n"
     ]
    }
   ],
   "source": [
    "# 8.字典的键或值的返回\n",
    "# 键key的集合  ---> keys方法\n",
    "print(stud.keys())\n",
    "# 值value的集合  ---> values方法\n",
    "print(stud.values())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "id": "65b5acc8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_items([(1001, '小明'), (1002, '李华'), (1003, '李文'), (1004, '李琳'), (1005, '小文'), (1006, '李贺'), (1010, '小兰')])\n"
     ]
    }
   ],
   "source": [
    "# 9.字典中 items 方法\n",
    "# items方法将字典所有的键/值对以列表方式返回，返回时没有特定的次序（因为字典本身无序）\n",
    "print(stud.items())   # 字典以列表的形式展现，每对键值用元组的方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "id": "bc476c28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gallahad the pure\n",
      "robin the brave\n"
     ]
    }
   ],
   "source": [
    "# items在for循环中的使用\n",
    "knights = {'gallahad': 'the pure', 'robin': 'the brave'}\n",
    "for k, v in knights.items():     # items 有多个对应的变量 在字典中 利用for循环可以把键和值分别展现出来 \n",
    "    print(k, v)  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cad03704",
   "metadata": {},
   "source": [
    "* 10.字典中fromkeys()方法\n",
    "  * fromkeys() 方法用于创建一个新的字典，并以可迭代对象中的元素分别作为字典中的键，且所有键对应同一个值，默认为None。\n",
    "  * 语法： dict.fromkeys(key[,value=None])\n",
    "  * iterable --> 用于创建新的字典的键的可迭代对象（字符串、列表、元祖、字典）\n",
    "  * value --> 可选参数, 字典所有键对应同一个值的初始值，默认为None\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "id": "c11bd8e3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'1': '字符串', '2': '字符串'}\n",
      "{1: '列表', 2: '列表'}\n",
      "{1: '元祖', 2: '元祖'}\n",
      "{1: '字典', 2: '字典'}\n",
      "{1: None, 2: None}\n"
     ]
    }
   ],
   "source": [
    "key1 = \"12\" # 字符串\n",
    "key2 = [1,2] # 列表\n",
    "key3 = (1,2) # 元组\n",
    "key4 = {1:'one',2:'two'} # 字典\n",
    "d1 = dict.fromkeys(key1,'字符串')\n",
    "d2 = dict.fromkeys(key2,'列表')\n",
    "d3 = dict.fromkeys(key3,'元祖')\n",
    "d4 = dict.fromkeys(key4,'字典')\n",
    "d5 = dict.fromkeys(key4)    # value默认为None\n",
    "print(d1)\n",
    "print(d2)\n",
    "print(d3)\n",
    "print(d4)\n",
    "print(d5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97216d8f",
   "metadata": {},
   "source": [
    "* 11.setdefault方法 \n",
    "  * 可以同键来获取对应的值，与get方法类似 但如果键不存在于字典中，将会添加键并将值设为默认值。\n",
    "  * 语法：dict.setdefault(key, default=None)\n",
    "  * key -- 查找的键值。\n",
    "  * default -- 键不存在时，设置的默认键值。\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "id": "a436af18",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'xiao ming', 'age': 12, 'id': 'student'}\n",
      "12\n",
      "None\n",
      "{'name': 'xiao ming', 'age': 12, 'id': 'student', 'job': None}\n"
     ]
    }
   ],
   "source": [
    "a = {\"name\":\"xiao ming\",\n",
    "     \"age\":12,\n",
    "     \"id\":\"student\"\n",
    "}\n",
    "print(a)\n",
    "print(a.setdefault('age'))  # 查找字典中已经存在的值\n",
    "print(a.setdefault(\"job\"))  # 查找字典中不存在的值\n",
    "print(a)    # 已知job这个键不存在 则会被加到a字典中 并赋予值为None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8f3b2c3b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
